﻿using System;
using System.Linq;
using System.Collections;
using System.Text;
using System.Text.RegularExpressions;

namespace george.Helper {
    public static class StringHelper {
		/// <summary>
		/// 返回一个字符串，该字符串包含从某字符串左侧算起的指定数量的字符。
		/// </summary>
		/// <param name="str">从中返回最左侧的那些字符。 </param>
		/// <param name="length"> 指示要返回的字符数的数值表达式。 
		/// 如果为 0，则返回零长度字符串 (string.Empty)。 
		/// 如果大于或等于 str 的字符数，则返回整个字符串。
		/// 如果是负数则相当于调用Right(-lenght);
		///  </param>
		/// <see cref="Right"/>
		/// <returns>返回一个字符串，该字符串包含从某字符串左侧算起的指定数量的字符。</returns>
		public static string Left(this string str, int length){
			if (length == 0)
				return string.Empty;
			if (length == str.Length)
				return str;
			if (length < 0)
				return str.Right(-length);
			if (length > 0)
				length = Math.Min(str.Length, length);
			return str.Substring(0, length);
		}
		/// <summary>
		/// 返回一个字符串，该字符串包含从某字符串右侧算起的指定数量的字符。
		/// </summary>
		/// <param name="str">从中返回最右侧的那些字符。 </param>
		/// <param name="length"> 指示要返回的字符数的数值表达式。 
		/// 如果为 0，则返回零长度字符串 (string.Empty)。 
		/// 如果大于或等于 str 的字符数，则返回整个字符串。
		/// 如果是负数则相当于调用Right(-lenght);
		///  </param>
		/// <see cref="Left"/>
		/// <returns>返回一个字符串，该字符串包含从某字符串右侧算起的指定数量的字符。</returns>
		public static string Right(this string str, int length){
			if (length == 0)
				throw new ArgumentOutOfRangeException("length", "长度不能为0");
			if (length == str.Length)
				return str;
			if (length < 0)
				return str.Left(-length);
			if (length > 0)
				length = Math.Min(str.Length, length);
			return str.Substring(str.Length - length, length);
		}
		/// <summary>
		/// 只要队列里面有一个项目符合要求就返回 true
		/// </summary>
		/// <param name="str"></param>
		/// <param name="arr"></param>
		/// <param name="IgnoreCase"></param>
		/// <returns></returns>
		public static bool EndsWith(this string str, IQueryable arr, bool IgnoreCase = true){
			foreach (var item in arr){
				if (IgnoreCase) {
					if (str.EndsWith(item.ToString(), StringComparison.OrdinalIgnoreCase))
						return true;
				} else {
					if (str.EndsWith(item.ToString()))
						return true;
				}
			}
			return false;
		}
		/// <summary>
		/// 格式化字符串
		/// </summary>
		/// <param name="format"></param>
		/// <param name="args"></param>
		/// <returns></returns>
		public static string FormatMe(this string format, params object[] args) {
			return string.Format(format, args);
		}

        public static string SqlInjectionAll(string value) {
            if (string.IsNullOrEmpty(value)) return string.Empty;
            value = value.Replace( @";", string.Empty);
            value = value.Replace( @"'", string.Empty);
            value = value.Replace( @"&", string.Empty);
            value = value.Replace( @"%20", string.Empty);
            value = value.Replace( @"--", string.Empty);
            value = value.Replace( @"=", string.Empty);
            value = value.Replace( @"==", string.Empty);
            value = value.Replace( @"<", string.Empty);
            value = value.Replace( @">", string.Empty);
            value = value.Replace( @"%", string.Empty);
            value = value.Replace( @"1=1", string.Empty);
            value = value.Replace( @"1==1", string.Empty);
            value = Regex.Replace(value, @"truncate", string.Empty, RegexOptions.IgnoreCase);
            value = Regex.Replace(value, @"delete", string.Empty, RegexOptions.IgnoreCase);
            value = Regex.Replace(value, @"drop", string.Empty, RegexOptions.IgnoreCase);
            value = Regex.Replace(value, @"xp_cmdshell", string.Empty, RegexOptions.IgnoreCase);
            value = Regex.Replace(value, @"exec", string.Empty, RegexOptions.IgnoreCase);
            value = Regex.Replace(value, @"update", string.Empty, RegexOptions.IgnoreCase);
            value = Regex.Replace(value, @"net", string.Empty, RegexOptions.IgnoreCase);
            value = Regex.Replace(value, @"insert", string.Empty, RegexOptions.IgnoreCase);
            value = Regex.Replace(value, @"or", string.Empty, RegexOptions.IgnoreCase);
            return value;
        }

        /// <summary>
        /// 连结
        /// </summary>
        /// <param name="separator"></param>
        /// <param name="list"></param>
        /// <returns></returns>
        public static string Join(this string separator, IEnumerable list) {
			if (list == null) return string.Empty;
			var sb = new StringBuilder();
			var first = true;
			foreach (var item in list) {
				if (first) {
					sb.Append(item.ToString());
					first = false;
				} else {
					sb.AppendFormat("{0}{1}",separator,item);
				}
			}
			return sb.ToString();
		}
		public static string Join(this IEnumerable list, string separator) {
			if (list == null) return string.Empty;
			var sb = new StringBuilder();
			var first = true;
			foreach (var item in list) {
				if (first) {
					sb.Append(item.ToString());
					first = false;
				} else {
					sb.AppendFormat("{0}{1}", separator, item);
				}
			}
			return sb.ToString();
		}
        public static string JoinToStr(this IEnumerable list, string separator)
        {
            if (list == null) return string.Empty;
            var sb = new StringBuilder();
            var first = true;
            foreach (var item in list)
            {
                if (first)
                {
                    sb.Append("'"+item.ToString()+"'");
                    first = false;
                }
                else
                {
                    sb.AppendFormat("{0}'{1}'", separator, item);
                }
            }
            return sb.ToString();
        }
        /// <summary>
        /// 去除字符串前的"0"
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string StartTrim(this string str)
        {
            return string.IsNullOrWhiteSpace(str) ? "" : str.TrimStart('0');
        }

		/// <summary>
		/// 是否整形数字
		/// </summary>
		/// <param name="str"></param>
		/// <returns></returns>
		public static bool IsInt(this string str) {
			var reg=new Regex("^-{0,1}\\d+$", RegexOptions.Compiled);
			return reg.IsMatch(str);
		}
		/// <summary>
		/// 是否是MD5编码
		/// </summary>
		/// <param name="str"></param>
		/// <param name="isLong">是否是32位</param>
		/// <returns></returns>
		public static bool IsMD5Code(this string str, bool isLong = true) {
			if (isLong) {
				var reg = new Regex("^([a-z0-9]{32})$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
				return reg.IsMatch(str);
			} else {
				var reg = new Regex("^([a-z0-9]{16})$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
				return reg.IsMatch(str);
			}
		}

		/// <summary>
		/// 是否是合法的邮箱地址（简单验证）
		/// </summary>
		/// <param name="email"></param>
		/// <returns></returns>
		public static bool IsEmail(this string email){
			email = email.Trim();
			if (email.Length < 5) return false;
			if (email.IndexOf('@') < 1) return false;
			if (email.IndexOf('.') < 3) return false;
			return true;
		}

		/// <summary>
		/// 是否是有效的电话号码
		/// </summary>
		/// <param name="str"></param>
		/// <returns></returns>
		public static bool IsTel(this string str) {
			str = str.Trim();
			var telReg = new Regex("^(13|15|17|18)\\d{9}$", RegexOptions.Compiled);
			if (telReg.IsMatch(str))
				return true;
			//带区号的固定号码
			var phoneReg=new Regex("^0\\d{2,4}[ -]{0,1}\\d{5,8}$", RegexOptions.Compiled);
			return phoneReg.IsMatch(str);
		}
		/// <summary>
		/// 判断string是否Ip地址
		/// </summary>
		/// <param name="str"></param>
		/// <returns></returns>
		public static bool IsIpaddress(this string str){
			str = str.Trim();
			var ipv4Reg = new Regex("^((?:(?:25[0-5]|2[0-4]\\d|((1\\d{2})|([1-9]?\\d)))\\.){3}(?:25[0-5]|2[0-4]\\d|((1\\d{2})|([1-9]?\\d))))$", RegexOptions.Compiled);
			if (ipv4Reg.IsMatch(str))
				return true;
			var ipv6Reg = new Regex("^([\\da-fA-F]{1,4}:){6}((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$|^::([\\da-fA-F]{1,4}:){0,4}((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$|^([\\da-fA-F]{1,4}:):([\\da-fA-F]{1,4}:){0,3}((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$|^([\\da-fA-F]{1,4}:){2}:([\\da-fA-F]{1,4}:){0,2}((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$|^([\\da-fA-F]{1,4}:){3}:([\\da-fA-F]{1,4}:){0,1}((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$|^([\\da-fA-F]{1,4}:){4}:((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$|^([\\da-fA-F]{1,4}:){7}[\\da-fA-F]{1,4}$|^:((:[\\da-fA-F]{1,4}){1,6}|:)$|^[\\da-fA-F]{1,4}:((:[\\da-fA-F]{1,4}){1,5}|:)$|^([\\da-fA-F]{1,4}:){2}((:[\\da-fA-F]{1,4}){1,4}|:)$|^([\\da-fA-F]{1,4}:){3}((:[\\da-fA-F]{1,4}){1,3}|:)$|^([\\da-fA-F]{1,4}:){4}((:[\\da-fA-F]{1,4}){1,2}|:)$|^([\\da-fA-F]{1,4}:){5}:([\\da-fA-F]{1,4})?$|^([\\da-fA-F]{1,4}:){6}:$", RegexOptions.Compiled);
			return false;
		}

        /// <summary>    
        /// 删除SQL注入特殊字符    
        /// 解然 20070622加入对输入参数sql为Null的判断    
        /// </summary>    
        public static string SqlInjection(this string sql) {
            if (string.IsNullOrEmpty(sql)) return sql;
            //过滤 ' --    
            const string pattern1 = @"(\%27)|(\')|(\-\-)";

            //防止执行 ' or    
            const string pattern2 = @"((\%27)|(\'))\s*((\%6F)|o|(\%4F))((\%72)|r|(\%52))";

            //防止执行sql server 内部存储过程或扩展存储过程    
            const string pattern3 = @"\s+exec(\s|\+)+(s|x)p\w+";

            sql = Regex.Replace(sql, pattern1, string.Empty, RegexOptions.IgnoreCase);
            sql = Regex.Replace(sql, pattern2, string.Empty, RegexOptions.IgnoreCase);
            sql = Regex.Replace(sql, pattern3, string.Empty, RegexOptions.IgnoreCase);
            return sql;
        }
        /// <summary>
        /// 转义 xml
        /// </summary>
        /// <param name="strInput"></param>
        /// <returns></returns>
        public static string ConvertXML(this string strInput) {
            strInput = strInput.Replace("&", "&amp;");
            strInput = strInput.Replace("<", "&lt;");
            strInput = strInput.Replace(">", "&gt;");
            strInput = strInput.Replace("'", "&#039;");
            //strInput = strInput.Replace("[", "");
            //strInput = strInput.Replace("]", "");
            return strInput;
        }

		/// <summary>
		/// 判断字符串是否可以转换成日期
		/// </summary>
		/// <param name="pStr">空（null或者长度0）返回 false</param>
		public static bool IsDateTime(string pStr) {
			if (string.IsNullOrWhiteSpace(pStr))
				return false;
			DateTime date;
			return DateTime.TryParse(pStr, out date);
		}
		/// <summary>
		/// 如果value为空则返回dv，否则返回value.Trim()
		/// </summary>
		/// <param name="value"></param>
		/// <param name="dv">不会对此参数做任何校验，请谨慎</param>
		/// <returns></returns>
		public static string Get(string value, string dv){
		    return string.IsNullOrWhiteSpace(value) ? dv : value.Trim();
	    }
		/// <summary>
		/// 检验身份证号码
		/// </summary>
		/// <see cref="http://wenku.baidu.com/link?url=ObNCpLGcPSVmPnD-RSrHorVM6M__nPQcEr60AzhHeZL_4FinhbqsnAuefPLZHsFPwvVovkwRhq_oI73k5VXY0tGgyYO2LPDRKDcPMWGGwym"/>
		/// <param name="str"></param>
		/// <returns></returns>
		public static bool IsIdentityCard(this string str) {
			if (str.Length != 18) return false;
			var reg = new Regex("^([1234568][0-9])(\\d{2})(\\d{2})([12]\\d{3})([01]\\d)([0123]\\d)(\\d{3})[0-9x]$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
			var m = reg.Match(str);
			if (m.Success == false)
				return false;
			var ds = string.Format("{0}-{1}-{2}", str.Substring(6, 4), str.Substring(10, 2), str.Substring(12, 2));
			DateTime d;
			if (!DateTime.TryParse(ds, out d)) {
				return false;
			}

			var ys = new[] { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
			var jym = new[] { "1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2" };
			var s = 0;
			for (var i = 0; i < 17; i++) {
				var c = int.Parse(str.Substring(i, 1));
				s += c * ys[i];
			}
			var mod = s % 11;
			return str.Substring(17, 1).ToUpper() == jym[mod];
		}

        /// <summary>
        /// 返回一个值，该值指示指定的子串是否出现在此字符串中。
        /// </summary>
        /// <param name="str">String</param>
        /// <param name="substring">要搜寻的字符串</param>
        /// <param name="comp">指定搜索规则的枚举值之一。</param>
        /// <returns> 
        /// 如果 true 参数出现在此字符串中，或者 value 为空字符串 ("")，则为 value；
        /// 否则为 false。
        /// </returns>
        public static bool Contains(this String str, String substring,
                       StringComparison comp)
        {
            if (substring == null)
                throw new ArgumentNullException("substring",
                                                "substring 不能为null");
            else if (!Enum.IsDefined(typeof(StringComparison), comp))
                throw new ArgumentException("comp is not a member of StringComparison",
                                            "comp");
            return str.IndexOf(substring, comp) >= 0;
        }


        /// <summary>
        /// 获取查询店铺控件传入的shopid,添加单引号和圆括号
        /// </summary>
        /// <remarks>
        /// eg.  KM000026,KM000055,KM000120
        /// 返回 ('KM000026','KM000055','KM000120')
        /// </remarks>
        /// <param name="ShopidShopIDs">eg.  KM000026,KM000055,KM000120</param>
        /// <returns>处理后的string,('KM000026','KM000055','KM000120')</returns>
        public static string GetString(this string ShopidShopIDs)
        {
            StringBuilder result = new StringBuilder();
            if (!string.IsNullOrWhiteSpace(ShopidShopIDs))
            {
                result.Append("(");
                string[] str = ShopidShopIDs.Split(',');
                for (var index = 0; index < str.Length; index++)
                {
                    result.Append("'");
                    result.Append(str[index]);
                    result.Append("'");
                    if (index + 1 != str.Length)
                    {
                        result.Append(",");
                    }
                }
                result.Append(")");
            }
            return result.ToString();
        }
        
        public static string GetSubString(this string SourceStr, string StartStr, string EndStr,
            out string KeyStr)
        {
            KeyStr = "";
            var startIndex = SourceStr.IndexOf(StartStr);
            var endIndex = SourceStr.LastIndexOf(EndStr);
            if (startIndex != -1 && endIndex != -1)
            {
                KeyStr = SourceStr.Substring(startIndex,
                    endIndex - startIndex + EndStr.Length);
                SourceStr = SourceStr.Replace(KeyStr, "");
                KeyStr = KeyStr.Replace(StartStr, "");
                KeyStr = KeyStr.Replace(EndStr, "");
                KeyStr = KeyStr.Trim();
            }
            return SourceStr.Trim();
        }

    }


    //end class
}//end namespace